package org.swxjava.servlet;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.swxjava.Container;
import org.swxjava.Remoter;
import org.swxjava.WebContextFactory.WebContextBuilder;
import org.swxjava.assembler.ConverterManager;
import org.swxjava.core.ServiceLocatorManager;
import org.swxjava.util.BeanUtils;
import org.swxjava.util.Log;
import org.swxjava.util.LogFactory;

public class DefaultContainer implements Container {
	
	/** Logger */
	private static final Log LOG = LogFactory.getLog(DefaultContainer.class);
	
	/**
	 * The beans that we know of indexed by type
	 */
	protected Map beans = new TreeMap();
	
	private ConverterManager converterManager;
	private ServiceLocatorManager serviceLocatorManager;
	private WebContextBuilder webContextBuilder;
	private Remoter remoter;

	public ConverterManager getConverterManager() {
		return converterManager;
	}

	public void setConverterManager(ConverterManager converterManager) {
		this.converterManager = converterManager;
	}

	public ServiceLocatorManager getServiceLocatorManager() {
		return serviceLocatorManager;
	}

	public void setServiceLocatorManager(ServiceLocatorManager serviceLocatorManager) {
		this.serviceLocatorManager = serviceLocatorManager;
	}

	public WebContextBuilder getWebContextBuilder() {
		return webContextBuilder;
	}

	public void setWebContextBuilder(WebContextBuilder webContextBuilder) {
		this.webContextBuilder = webContextBuilder;
	}

	public Remoter getRemoter() {
		return remoter;
	}

	public void setRemoter(Remoter remoter) {
		this.remoter = remoter;
	}

	public void addParameter(Object askFor, Object valueParam)
			throws InstantiationException, IllegalAccessException {
		Object value = valueParam;
		
		if (value instanceof String) {
			// value is a classname that needs instansiating
			try {
				Class impl = BeanUtils.getClassForName((String) value);
				value = impl.newInstance();
			} catch (IllegalArgumentException ex) {
			}
		}

		// If we have an instansiated value object and askFor is an interface
		// then we can check that one implements the other
		if (!(value instanceof String) && askFor instanceof String) {
			try {
				Class iface = BeanUtils.getClassForName((String) askFor);
				if (!iface.isAssignableFrom(value.getClass())) {
					LOG.error("Can't cast: " + value + " to " + askFor);
				}
			} catch (IllegalArgumentException ex) {
				// it's not a classname, leave it
			}
		}

		if (LOG.isDebugEnabled()) {
			if (value instanceof String) {
				LOG.debug("Adding container setting: " + askFor + "=" + value);
			} else {
				LOG.debug("Adding container implementation: " + askFor + "=" + value.getClass().getName());
			}
		}

		beans.put(askFor, value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.directwebremoting.Container#getBean(java.lang.String)
	 */
	public Object getBean(String id) {
		Object reply = beans.get(id);
		if (reply == null) {
			LOG.warn("No bean with id=" + id);
		}
		return reply;
	}

	public List getServiceNames() {
		// TODO Auto-generated method stub
		return null;
	}
}
